package jisuanji;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.text.DecimalFormat;
import java.util.ArrayList;


/* ===================== 画布 ===================== */
class RealCanvas extends JComponent {
    public final ArrayList<MyShape> list = new ArrayList<>();
    private double scale = 1.0;
    private Rectangle2D world = new Rectangle2D.Double();

    public RealCanvas() { setBackground(Color.WHITE); setOpaque(true); }

    public void addShape(MyShape s) {
        list.add(s);
        world = world.createUnion(s.getRealShape().getBounds2D());
        world = world.createUnion(new Rectangle2D.Double(0, 0, 100, 100));
        reScale(); revalidate(); repaint();
    }
    public void clear() { list.clear(); world = new Rectangle2D.Double(); scale = 1.0; repaint(); }
    public void removeLast() { if (!list.isEmpty()) list.remove(list.size() - 1); rebuildWorld(); reScale(); repaint(); }
    private void rebuildWorld() {
        world = new Rectangle2D.Double();
        for (MyShape s : list) world = world.createUnion(s.getRealShape().getBounds2D());
    }
    private void reScale() {
        if (world.isEmpty()) return;
        double margin = 20;
        double sx = (getWidth() - 2 * margin) / world.getWidth();
        double sy = (getHeight() - 2 * margin) / world.getHeight();
        scale = Math.min(sx, sy);
        if (scale <= 0) scale = 1;
    }
    public Dimension getPreferredSize() {
        if (world.isEmpty()) return new Dimension(800, 600);
        int w = (int)(world.getWidth() * scale + 40);
        int h = (int)(world.getHeight() * scale + 40);
        return new Dimension(w, h);
    }
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        AffineTransform at = new AffineTransform();
        at.translate(20, 20);
        at.scale(scale, scale);
        at.translate(-world.getMinX(), -world.getMinY());
        g2.transform(at);

        for (MyShape s : list) {
            Shape real = s.getRealShape();
            g2.setColor(new Color(30, 144, 255, 80));
            g2.fill(real);
            g2.setColor(Color.BLUE);
            g2.setStroke(new BasicStroke((float)(1.0 / scale)));
            g2.draw(real);
        }
        g2.dispose();
    }
}

/* ===================== 主界面 ===================== */
public class DynamicShapeGUI extends JFrame {
    private RealCanvas canvas = new RealCanvas();
    private JTextArea info = new JTextArea(10, 25);
    private JComboBox<String> chooser = new JComboBox<>(
            new String[]{"正方形", "长方形", "圆形", "三角形", "扇形", "梯形"});
    private CardLayout card = new CardLayout();
    private JPanel inputPanel = new JPanel(card);

    /* 输入控件 */
    private JTextField sqSide = new JTextField("50", 6);
    private JTextField reLen = new JTextField("80", 6), reWid = new JTextField("40", 6);
    private JTextField ciR = new JTextField("30", 6);
    private JTextField ta = new JTextField("40", 6), tb = new JTextField("50", 6), tc = new JTextField("60", 6);
    /* 新增 */
    private JTextField seAngle = new JTextField("60", 6);
    private JTextField trTop = new JTextField("30", 6), trBottom = new JTextField("50", 6), trHeight = new JTextField("20", 6);

    public DynamicShapeGUI() {
        super("动态真实尺寸图形计算器");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(1000, 700);
        setLocationRelativeTo(null);
        setGlobalFont();
        canvas.setMinimumSize(new Dimension(500, 400));

        inputPanel.add(genSquarePanel(), "正方形");
        inputPanel.add(genRectPanel(), "长方形");
        inputPanel.add(genCirclePanel(), "圆形");
        inputPanel.add(genTriPanel(), "三角形");
        inputPanel.add(genSectorPanel(), "扇形");   // 新增
        inputPanel.add(genTrapezoidPanel(), "梯形"); // 新增
        chooser.addActionListener(e -> card.show(inputPanel, (String) chooser.getSelectedItem()));

        JButton addBtn = new JButton("添加"), clearBtn = new JButton("清空"), delBtn = new JButton("撤销");
        addBtn.addActionListener(e -> addAction());
        clearBtn.addActionListener(e -> { canvas.clear(); info.setText("图形清单为空"); });
        delBtn.addActionListener(e -> { canvas.removeLast(); updateInfo(); });

        JPanel north = new JPanel(new BorderLayout());
        JPanel top = new JPanel();
        top.add(new JLabel("选择图形")); top.add(chooser);
        north.add(top, BorderLayout.NORTH);
        north.add(inputPanel, BorderLayout.CENTER);
        JPanel btnP = new JPanel(); btnP.add(addBtn); btnP.add(delBtn); btnP.add(clearBtn);
        north.add(btnP, BorderLayout.SOUTH);

        info.setEditable(false);
        info.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        info.setText("图形清单为空");

        JPanel rightPanel = new JPanel(new BorderLayout());
        rightPanel.add(info, BorderLayout.CENTER);
        rightPanel.setMinimumSize(new Dimension(280, 300));

        JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(canvas), rightPanel);
        sp.setDividerLocation(720);
        sp.setResizeWeight(0.7);

        add(north, BorderLayout.NORTH);
        add(sp, BorderLayout.CENTER);
        setVisible(true);
    }

    /* -------- 输入面板工具方法 -------- */
    private JPanel genSquarePanel() { JPanel p = new JPanel(); p.add(new JLabel("边长")); p.add(sqSide); return p; }
    private JPanel genRectPanel() { JPanel p = new JPanel(); p.add(new JLabel("长")); p.add(reLen); p.add(new JLabel("宽")); p.add(reWid); return p; }
    private JPanel genCirclePanel() { JPanel p = new JPanel(); p.add(new JLabel("半径")); p.add(ciR); return p; }
    private JPanel genTriPanel() { JPanel p = new JPanel(); p.add(new JLabel("边a")); p.add(ta); p.add(new JLabel("边b")); p.add(tb); p.add(new JLabel("边c")); p.add(tc); return p; }
    private JPanel genSectorPanel() { JPanel p = new JPanel(); p.add(new JLabel("半径")); p.add(ciR); p.add(new JLabel("圆心角(°)")); p.add(seAngle); return p; }
    private JPanel genTrapezoidPanel() { JPanel p = new JPanel(); p.add(new JLabel("上底")); p.add(trTop); p.add(new JLabel("下底")); p.add(trBottom); p.add(new JLabel("高")); p.add(trHeight); return p; }

    /* -------- 添加图形 -------- */
    private void addAction() {
        MyShape s = null;
        try {
            switch ((String) chooser.getSelectedItem()) {
                case "正方形": s = new Square(Double.parseDouble(sqSide.getText())); break;
                case "长方形": s = new Rectangle(Double.parseDouble(reLen.getText()), Double.parseDouble(reWid.getText())); break;
                case "圆形": s = new Circle(Double.parseDouble(ciR.getText())); break;
                case "三角形": s = new Triangle(Double.parseDouble(ta.getText()), Double.parseDouble(tb.getText()), Double.parseDouble(tc.getText())); break;
                case "扇形": s = new Sector(Double.parseDouble(ciR.getText()), Double.parseDouble(seAngle.getText())); break;
                case "梯形": s = new Trapezoid(Double.parseDouble(trTop.getText()), Double.parseDouble(trBottom.getText()), Double.parseDouble(trHeight.getText())); break;
            }
        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "请输入合法数字！");
            return;
        }
        canvas.addShape(s);
        updateInfo();
    }

    /* -------- 更新右侧信息 -------- */
    private void updateInfo() {
        if (canvas.list.isEmpty()) {
            info.setText("图形清单为空");
            return;
        }
        StringBuilder sb = new StringBuilder();
        sb.append("=== 图形清单 ===\n\n");
        double sumArea = 0, sumPeri = 0;
        for (MyShape sh : canvas.list) {
            sb.append(sh.getInfo()).append("\n------------------------\n");
            sumArea += sh.getArea();
            sumPeri += sh.getPerimeter();
        }
        DecimalFormat df = new DecimalFormat("#.##");
        sb.append("\n=== 汇总 ===\n");
        sb.append("总面积：").append(df.format(sumArea)).append("\n");
        sb.append("总周长：").append(df.format(sumPeri));
        info.setText(sb.toString());
    }

    /* -------- 全局字体 -------- */
    private void setGlobalFont() {
        Font f = new Font("微软雅黑", Font.PLAIN, 14);
        UIManager.put("Label.font", f);
        UIManager.put("Button.font", f);
        UIManager.put("TextField.font", f);
        UIManager.put("TextArea.font", f);
        UIManager.put("ComboBox.font", f);
    }

    /* -------- main -------- */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(DynamicShapeGUI::new);
    }
}